package profile

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"mime"
	"net/http"
	"strings"
	"time"
	"usercenter/internal/middleware"
	"usercenter/internal/svc"
	"usercenter/internal/types"

	"github.com/minio/minio-go/v7"
	"github.com/zeromicro/go-zero/core/logx"
)

type UploadAvatarLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUploadAvatarLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadAvatarLogic {
	return &UploadAvatarLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UploadAvatarLogic) UploadAvatar(req *types.AvatarUploadRequest) (resp *types.AvatarUploadResponse, err error) {
	// 1. 验证文件大小 (限制为2MB)
	if len(req.File) > 2<<20 { // 2MB
		return nil, errors.New("文件大小不能超过2MB")
	}

	// 2. 获取用户ID (从上下文中获取，由Auth中间件设置)
	userId, ok := l.ctx.Value(middleware.UserIdKey).(int)
	if !ok {
		return nil, errors.New("获取用户信息失败")
	}

	// 3. 验证文件类型 (只允许图片)
	contentType := http.DetectContentType(req.File)
	if !strings.HasPrefix(contentType, "image/") {
		return nil, errors.New("只允许上传图片文件")
	}

	// 4. 生成唯一文件名和扩展名
	ext := ".jpg" // 默认后缀
	if detectedExt, err := mime.ExtensionsByType(contentType); err == nil && len(detectedExt) > 0 {
		ext = detectedExt[0] // 使用检测到的第一个扩展名
	}
	objectName := fmt.Sprintf("avatars/%d-%d%s", userId, time.Now().Unix(), ext)

	// 5. 上传到Minio/S3
	uploadInfo, err := l.svcCtx.MinioClient.PutObject(
		l.ctx,
		l.svcCtx.Config.Minio.BucketName, // 从配置中获取桶名
		objectName,
		bytes.NewReader(req.File),
		int64(len(req.File)),
		minio.PutObjectOptions{
			ContentType: contentType,
		},
	)
	if err != nil {
		logx.Errorf("上传头像到Minio失败: %v", err)
		return nil, errors.New("上传头像失败")
	}
	logx.Infof("头像上传成功: %+v", uploadInfo)

	// 6. 生成访问URL (根据配置决定是否使用SSL)
	var avatarURL string
	if l.svcCtx.Config.Minio.UseSSL {
		avatarURL = fmt.Sprintf("https://%s/%s/%s", l.svcCtx.Config.Minio.Endpoint, l.svcCtx.Config.Minio.BucketName, objectName)
	} else {
		avatarURL = fmt.Sprintf("http://%s/%s/%s", l.svcCtx.Config.Minio.Endpoint, l.svcCtx.Config.Minio.BucketName, objectName)
	}

	// 7. 更新数据库中的头像URL
	err = l.svcCtx.UserModel.UpdateAvatar(userId, avatarURL)
	if err != nil {
		logx.Errorf("更新用户头像URL失败: %v", err)
		return nil, errors.New("更新用户头像失败")
	}

	// 8. 返回成功响应
	return &types.AvatarUploadResponse{
		Code:    0,
		Message: "头像上传成功",
		Data: types.AvatarURL{
			AvatarURL: avatarURL,
		},
	}, nil
}
